package cn.iocoder.yudao.module.of.service.meetingInfo;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.iocoder.yudao.framework.common.core.SysConstants;
import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
import cn.iocoder.yudao.module.infra.dal.mysql.file.FileMapper;
import cn.iocoder.yudao.module.of.controller.admin.meetingminutes.vo.MeetingMinutesRespVO;
import cn.iocoder.yudao.module.of.controller.admin.meetingpart.vo.MeetingPartRespVO;
import cn.iocoder.yudao.module.of.controller.admin.taskhandler.vo.TaskHandlerRespVO;
import cn.iocoder.yudao.module.of.dal.dataobject.meetingminutes.MeetingMinutesDO;
import cn.iocoder.yudao.module.of.dal.dataobject.meetingminutesenduser.MeetingMinuteSendUserDO;
import cn.iocoder.yudao.module.of.dal.dataobject.meetingpart.MeetingPartDO;
import cn.iocoder.yudao.module.of.dal.dataobject.taskfeedback.TaskFeedbackDO;
import cn.iocoder.yudao.module.of.dal.dataobject.taskgenuser.TaskGenUserDO;
import cn.iocoder.yudao.module.of.dal.dataobject.taskhandler.TaskHandlerDO;
import cn.iocoder.yudao.module.of.dal.dataobject.taskinfo.TaskInfoDO;
import cn.iocoder.yudao.module.of.dal.mysql.meetingminutes.MeetingMinutesMapper;
import cn.iocoder.yudao.module.of.dal.mysql.meetingminutesenduser.MeetingMinuteSendUserMapper;
import cn.iocoder.yudao.module.of.dal.mysql.meetingpart.MeetingPartMapper;
import cn.iocoder.yudao.module.of.dal.mysql.taskfeedback.TaskFeedbackMapper;
import cn.iocoder.yudao.module.of.dal.mysql.taskgenuser.TaskGenUserMapper;
import cn.iocoder.yudao.module.of.dal.mysql.taskhandler.TaskHandlerMapper;
import cn.iocoder.yudao.module.of.dal.mysql.taskinfo.TaskInfoMapper;
import cn.iocoder.yudao.module.of.enums.DicConstants;
import cn.iocoder.yudao.module.of.enums.TaskStatusEnum;
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.UserDeptDO;
import cn.iocoder.yudao.module.system.dal.mysql.dept.DeptMapper;
import cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper;
import cn.iocoder.yudao.module.system.dal.mysql.user.UserDeptMapper;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.log4j.Log4j2;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import cn.iocoder.yudao.module.of.controller.admin.meetingInfo.vo.*;
import cn.iocoder.yudao.module.of.dal.dataobject.meetingInfo.MeetingInfoDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.of.dal.mysql.meetingInfo.MeetingInfoMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.of.enums.ErrorCodeConstants.*;

/**
 * 会议信息 Service 实现类
 *
 * @author 超级管理员
 */
@Service
@Validated
@Log4j2
public class MeetingInfoServiceImpl implements MeetingInfoService {

    @Resource
    private MeetingInfoMapper meetingInfoMapper;
    @Resource
    private MeetingPartMapper meetingPartMapper;
    @Resource
    private TaskInfoMapper taskInfoMapper;
    @Resource
    private DeptMapper deptMapper;
    @Resource
    private AdminUserMapper userMapper;
    @Resource
    private FileMapper fileMapper;
    @Resource
    private TaskHandlerMapper taskHandlerMapper;
    @Resource
    private TaskFeedbackMapper taskFeedbackMapper;
    @Resource
    private TaskGenUserMapper taskGenUserMapper;
    @Resource
    private MeetingMinutesMapper  meetingMinutesMapper;
    @Resource
    private MeetingMinuteSendUserMapper meetingMinuteSendUserMapper;
    @Resource
    private UserDeptMapper userDeptMapper;

    @Resource
    private RedisTemplate<String, Long> redisTemplate;

    private static final String ATOM_ID_KEY = "meeting:code:%s:";

    private static final String TASK_CODE_FORMAT = "HY%s%s";

    /**
     * 获得原子序列号
     *
     * @return 结果
     */
    public long getAtomId(String key) {
        // 原子递增操作
        Long result = redisTemplate.opsForValue().increment(key, 1L);

        // 设置过期时间
        redisTemplate.expire(key, Duration.ofDays(1));

        return result != null ? result : 0;
    }

    @Override
    public String geMeetingCode() {

        String dateFormat = DateUtil.format(new Date(), "yyyyMMdd");
        String cacheKey = String.format(ATOM_ID_KEY, dateFormat);
        String atomId = NumberUtil.decimalFormat("000", getAtomId(cacheKey));
        return String.format(TASK_CODE_FORMAT, dateFormat, atomId);
    }


    @Override
    public Long createMeetingInfo(MeetingInfoSaveReqVO createReqVO) {
        // 插入
        MeetingInfoDO meetingInfo = BeanUtils.toBean(createReqVO, MeetingInfoDO.class);
        LocalDateTime meetingTime = meetingInfo.getStartTime();
        if(meetingInfo.getTimeLongType() != null) {
            //计算截止时间
            Integer timeLongType = meetingInfo.getTimeLongType().intValue();
            meetingInfo.setEndTime(meetingTime.plusMinutes(timeLongType*30));
            meetingInfo.setTimeLong(timeLongType*30);
        }else if(meetingInfo.getEndTime() != null){
            Duration duration = Duration.between(meetingInfo.getStartTime(), meetingInfo.getEndTime());
            Long aLong = Long.valueOf(duration.toMinutes());
            meetingInfo.setTimeLong(aLong.intValue());
        }
        meetingInfo.setTenantId(TenantContextHolder.getTenantId());
        meetingInfo.setCode(geMeetingCode());
        meetingInfoMapper.insert(meetingInfo);

        Set<String> participants = createReqVO.getParticipants();
        List<MeetingPartDO> list = new ArrayList<>();
        for(String part:participants){
            String[] split = part.split("-");
            MeetingPartDO partDO = new MeetingPartDO();
            partDO.setDeptId(Long.valueOf(split[0]));
            partDO.setUserId(Long.valueOf(split[1]));
            partDO.setMeetingId(meetingInfo.getId());
            list.add(partDO);
        }
        if(!list.isEmpty()){
            meetingPartMapper.insert(list);
        }
        // 返回
        return meetingInfo.getId();
    }

    @Override
    @Transactional
    public void updateMeetingInfo(MeetingInfoSaveReqVO updateReqVO) {
        // 校验存在
        validateMeetingInfoExists(updateReqVO.getId());
        // 更新
        MeetingInfoDO updateObj = BeanUtils.toBean(updateReqVO, MeetingInfoDO.class);
        LocalDateTime meetingTime = updateObj.getStartTime();
        if(updateObj.getTimeLongType() != null) {
            //计算截止时间
            Integer timeLongType = updateObj.getTimeLongType().intValue();
            updateObj.setEndTime(meetingTime.plusMinutes(timeLongType * 30));
            updateObj.setTimeLong(timeLongType * 30);
        }else if(updateObj.getEndTime() != null){
            Duration duration = Duration.between(updateObj.getStartTime(), updateObj.getEndTime());
            Long aLong = Long.valueOf(duration.toMinutes());
            updateObj.setTimeLong(aLong.intValue());
        }
        meetingInfoMapper.updateById(updateObj);
        Set<String> participants = updateReqVO.getParticipants();
        if(participants != null && !participants.isEmpty()){
            meetingPartMapper.delete(MeetingPartDO::getMeetingId,updateReqVO.getId());
            List<MeetingPartDO> list = new ArrayList<>();
            for(String part:participants){
                String[] split = part.split("-");
                MeetingPartDO partDO = new MeetingPartDO();
                partDO.setDeptId(Long.valueOf(split[0]));
                partDO.setUserId(Long.valueOf(split[1]));
                partDO.setMeetingId(updateObj.getId());
                list.add(partDO);
            }
            if(!list.isEmpty()){
                meetingPartMapper.insert(list);
            }
        }

    }

    @Override
    public void sendDept(MeetingInfoSaveReqVO updateReqVO) {
        // 校验存在
        List<MeetingMinutesDO> meetingMinuteList = updateReqVO.getMeetingMinuteList();
        for(MeetingMinutesDO meetingMinutesDO:meetingMinuteList){
            if (meetingMinutesMapper.selectById(meetingMinutesDO.getId()) == null) {
                throw exception(MEETING_MINUTES_NOT_EXISTS);
            }
            if(meetingMinutesDO.getMainRespDeptId() != null) {
                DeptDO deptDO = deptMapper.selectById(meetingMinutesDO.getMainRespDeptId());
                if (deptDO != null) {
                    //获取部门负责人
                    Long leaderUserId = deptDO.getLeaderUserId();
                    if (leaderUserId == null) {
                        leaderUserId = deptDO.getRespLeaderUserId();
                    }
                    meetingMinutesDO.setMainRespDeptName(deptDO.getName());
                    meetingMinutesDO.setMainRespUserId(leaderUserId);
                    meetingMinutesDO.setTaskGenUserId(-1l);
                }
            }
            if(meetingMinutesDO.getTaskGenUserId() != null){
                meetingMinutesDO.setTaskGenUserId(meetingMinutesDO.getTaskGenUserId());
                meetingMinutesDO.setTaskGenUserName(meetingMinutesDO.getTaskGenUserName());
                TaskGenUserDO genUserDO = new TaskGenUserDO();
                genUserDO.setTaskGenUserId(meetingMinutesDO.getTaskGenUserId());
                genUserDO.setTaskGenUserName(meetingMinutesDO.getTaskGenUserName());
                genUserDO.setTaskType(1);
                genUserDO.setMeetingId(updateReqVO.getId());
                taskGenUserMapper.insert(genUserDO);

            }
        }
        meetingMinutesMapper.updateBatch(meetingMinuteList);
    }

    @Override
    public void deleteMeetingInfo(Long id) {
        // 校验存在
        validateMeetingInfoExists(id);
        // 删除
        meetingInfoMapper.deleteById(id);
    }

    private void validateMeetingInfoExists(Long id) {
        if (meetingInfoMapper.selectById(id) == null) {
            throw exception(MEETING_INFO_NOT_EXISTS);
        }
    }

    @Override
    public MeetingInfoRespVO getMeetingInfo(Long id) {
        MeetingInfoDO meetingInfoDO = meetingInfoMapper.selectById(id);
        MeetingInfoRespVO meetingInfoRespVO = BeanUtils.toBean(meetingInfoDO, MeetingInfoRespVO.class);
        Set<Long> attachs = meetingInfoDO.getAttachs();
        if( attachs != null && !attachs.isEmpty()){
            List<FileDO> fileDOS = fileMapper.selectList(FileDO::getId, attachs);
            meetingInfoRespVO.setAttachList(fileDOS);
        }
        Set<Long> agendaAttachs = meetingInfoDO.getAgendaAttachs();
        if( attachs != null && !attachs.isEmpty()){
            List<FileDO> fileDOS = fileMapper.selectList(FileDO::getId, agendaAttachs);
            meetingInfoRespVO.setAgendaAttachList(fileDOS);
        }
        List<MeetingMinutesDO> meetingMinutesDOS = meetingMinutesMapper.selectList(MeetingMinutesDO::getMeetingId, id);
        List<MeetingMinutesRespVO>  mmList = meetingMinutesDOS.stream().map(mm -> {
            MeetingMinutesRespVO minutesRespVO = BeanUtils.toBean(mm, MeetingMinutesRespVO.class);
            Long minuteAttach = mm.getMinuteAttach();
            if(minuteAttach != null){
                minutesRespVO.setMinuteAttachFile(fileMapper.selectById(minuteAttach));
            }
            return minutesRespVO;
        }).collect(Collectors.toList());
        //设置会议参与者
        MPJLambdaWrapperX<MeetingPartDO> userWrapper = new MPJLambdaWrapperX<>();
        userWrapper.select(AdminUserDO::getNickname).distinct();
        userWrapper.eq(MeetingPartDO::getMeetingId,id);
        userWrapper.innerJoin(AdminUserDO.class,AdminUserDO::getId,MeetingPartDO::getUserId);
        List<Map<String, Object>> maps = meetingPartMapper.selectMaps(userWrapper);
        if(!maps.isEmpty()){
            List<String> nickname = maps.stream().map(user -> (String)user.get("nickname")).collect(Collectors.toList());
            meetingInfoRespVO.setParticipantsList(nickname);
        }

        meetingInfoRespVO.setMinuteList(mmList);
        return meetingInfoRespVO;
    }

    @Override
    public PageResult<MeetingInfoRespVO> getMeetingInfoPage(MeetingInfoPageReqVO pageReqVO) {
        MPJLambdaWrapperX<MeetingInfoDO> queryWrapper = new MPJLambdaWrapperX<>();
        String alias = queryWrapper.getAlias();
        queryWrapper.likeIfPresent(MeetingInfoDO::getName, pageReqVO.getName())
                .eqIfPresent(MeetingInfoDO::getTypeId, pageReqVO.getTypeId())
                .likeIfPresent(MeetingInfoDO::getCode, pageReqVO.getCode())
                .eqIfPresent(MeetingInfoDO::getChairpersonId, pageReqVO.getChairpersonId())
                .likeIfPresent(MeetingInfoDO::getChairpersonName, pageReqVO.getChairpersonName())
                .betweenIfPresent(MeetingInfoDO::getStartTime, pageReqVO.getStartTime())
                .betweenIfPresent(MeetingInfoDO::getEndTime, pageReqVO.getEndTime())
                .eqIfPresent(MeetingInfoDO::getTimeLong, pageReqVO.getTimeLong())
                .eqIfPresent(MeetingInfoDO::getAddress, pageReqVO.getAddress())
                .eqIfPresent(MeetingInfoDO::getAgenda, pageReqVO.getAgenda())
                .eqIfPresent(MeetingInfoDO::getPriorityId, pageReqVO.getPriorityId())
                .likeIfPresent(MeetingInfoDO::getPriorityName, pageReqVO.getPriorityName())
                .betweenIfPresent(MeetingInfoDO::getCreateTime, pageReqVO.getCreateTime())
                .eqIfPresent(MeetingInfoDO::getMainRespDeptId, pageReqVO.getMainRespDeptId())
                .likeIfPresent(MeetingInfoDO::getMainRespDeptName, pageReqVO.getMainRespDeptName())
                .eqIfPresent(MeetingInfoDO::getMainRespUserId, pageReqVO.getMainRespUserId());

        List<UserDeptDO> userDeptDOS = userDeptMapper.selectList(UserDeptDO::getUserId, WebFrameworkUtils.getLoginUserId());
        Boolean flag = false;
        for(UserDeptDO ud:userDeptDOS){
            if(ud.getDeptId() == SysConstants.JT_LEADER_DEPT.longValue()){
                flag =true;
                break;
            }
        }
        //不是领导班子成员
        if(!flag) {
            //我的会议 会议创建人  、会议主持人、会议参与人
            if(pageReqVO.getRole()  != null && pageReqVO.getRole() ==1){
                queryWrapper.eq(MeetingInfoDO::getCreator, WebFrameworkUtils.getLoginUserId());
            } else  if(pageReqVO.getRole()  != null && pageReqVO.getRole() ==2){
                queryWrapper.and(wrap -> wrap.eq(MeetingInfoDO::getChairpersonId, WebFrameworkUtils.getLoginUserId())
                        .or().exists("select 1 from of_meeting_part pt where   " + alias + ".id = pt.meeting_id and pt.user_id =" + WebFrameworkUtils.getLoginUserId())
                );
            }else {
                queryWrapper.and(wrap -> wrap.eq(MeetingInfoDO::getCreator, WebFrameworkUtils.getLoginUserId())
                        .or().eq(MeetingInfoDO::getChairpersonId, WebFrameworkUtils.getLoginUserId())
                        .or().exists("select 1 from of_meeting_part pt where   " + alias + ".id = pt.meeting_id and pt.user_id =" + WebFrameworkUtils.getLoginUserId())
                );
            }
        }

        if(pageReqVO.getStatus() != null){
            if(pageReqVO.getStatus() ==1){
                queryWrapper.gtIfPresent(MeetingInfoDO::getStartTime,new DateTime());
            }else  if(pageReqVO.getStatus() ==3){
                queryWrapper.ltIfPresent(MeetingInfoDO::getEndTime,new DateTime());
            }else{
                queryWrapper.leIfPresent(MeetingInfoDO::getStartTime,new DateTime())
                        .geIfPresent(MeetingInfoDO::getEndTime,new DateTime());
            }
        }

        PageResult<MeetingInfoDO> pageResult = meetingInfoMapper.selectPage(pageReqVO, queryWrapper);
        List<MeetingInfoDO> list = pageResult.getList();
        List<MeetingInfoRespVO> collect = list.stream().map(item -> {
            MeetingInfoRespVO RespVO = BeanUtils.toBean(item, MeetingInfoRespVO.class);

            MPJLambdaWrapperX<MeetingPartDO> userWrapper = new MPJLambdaWrapperX<>();
            userWrapper.select(AdminUserDO::getNickname).distinct();
            userWrapper.eq(MeetingPartDO::getMeetingId,item.getId());
            userWrapper.innerJoin(AdminUserDO.class,AdminUserDO::getId,MeetingPartDO::getUserId);
            List<Map<String, Object>> maps = meetingPartMapper.selectMaps(userWrapper);
            if(!maps.isEmpty()){
                List<String> nickname = maps.stream().map(user -> (String)user.get("nickname")).collect(Collectors.toList());
                RespVO.setParticipantsList(nickname);
            }
            Set<Long> agendaAttachs = item.getAgendaAttachs();
            if(agendaAttachs != null && !agendaAttachs.isEmpty()) {
                List<FileDO> fileDOS = fileMapper.selectList(FileDO::getId, agendaAttachs);
                if (!fileDOS.isEmpty()) {
                    RespVO.setAgendaAttachList(fileDOS);
                }
            }

            Set<Long> attachs = item.getAttachs();
            if(attachs != null && !attachs.isEmpty()) {
                List<FileDO> fileDOS = fileMapper.selectList(FileDO::getId, attachs);
                if (!fileDOS.isEmpty()) {
                    RespVO.setAttachList(fileDOS);
                }
            }
            return RespVO;
        }).collect(Collectors.toList());

        PageResult<MeetingInfoRespVO> result = new PageResult<>() ;
        result.setList(collect).setTotal(pageResult.getTotal());
        return result;

    }

    @Override
    public PageResult<MeetingInfoRespVO> getMeetingMinutePage(MeetingInfoPageReqVO pageReqVO) {
        MPJLambdaWrapperX<MeetingInfoDO> queryWrapper = new MPJLambdaWrapperX<>();
        String alias = queryWrapper.getAlias();
        queryWrapper.likeIfPresent(MeetingInfoDO::getName, pageReqVO.getName())
                .eqIfPresent(MeetingInfoDO::getTypeId, pageReqVO.getTypeId())
                .eqIfPresent(MeetingInfoDO::getChairpersonId, pageReqVO.getChairpersonId())
                .likeIfPresent(MeetingInfoDO::getChairpersonName, pageReqVO.getChairpersonName())
                .betweenIfPresent(MeetingInfoDO::getStartTime, pageReqVO.getStartTime())
                .betweenIfPresent(MeetingInfoDO::getEndTime, pageReqVO.getEndTime())
                .eqIfPresent(MeetingInfoDO::getTimeLong, pageReqVO.getTimeLong())
                .eqIfPresent(MeetingInfoDO::getAddress, pageReqVO.getAddress())
                .eqIfPresent(MeetingInfoDO::getAgenda, pageReqVO.getAgenda())
                .eqIfPresent(MeetingInfoDO::getPriorityId, pageReqVO.getPriorityId())
                .likeIfPresent(MeetingInfoDO::getPriorityName, pageReqVO.getPriorityName())
                .betweenIfPresent(MeetingInfoDO::getCreateTime, pageReqVO.getCreateTime())
                .eqIfPresent(MeetingInfoDO::getMainRespDeptId, pageReqVO.getMainRespDeptId())
                .likeIfPresent(MeetingInfoDO::getMainRespDeptName, pageReqVO.getMainRespDeptName())
                .eqIfPresent(MeetingInfoDO::getMainRespUserId, pageReqVO.getMainRespUserId());

        //我的会议 会议创建人  、会议主持人、会议参与人
        if(pageReqVO.getMinuteCreateTime() != null   && pageReqVO.getMinuteCreateTime().length>=2 && pageReqVO.getMinuteCreator() != null){
            queryWrapper.exists("select 1 from of_meeting_minutes mm where "+alias+".id = mm.meeting_id and mm.create_time >= '"+pageReqVO.getMinuteCreateTime()[0]+"'"
                    +" and mm.create_time  < '"+pageReqVO.getMinuteCreateTime()[1]+"'"
                    +" and mm.creator_name like '%"+ pageReqVO.getMinuteCreator()+"%'"
                 );
        }else if(pageReqVO.getMinuteCreateTime() != null && pageReqVO.getMinuteCreateTime().length>=2){
            queryWrapper.exists("select 1 from of_meeting_minutes mm where "+alias+".id = mm.meeting_id and mm.create_time >= '"+pageReqVO.getMinuteCreateTime()[0]+"'"
                    +" and mm.create_time  < '"+pageReqVO.getMinuteCreateTime()[1]+"'");
        }else if(pageReqVO.getMinuteCreator() != null){
            queryWrapper.exists("select 1 from of_meeting_minutes mm where "+alias+".id = mm.meeting_id "
                    +" and mm.creator_name like '%"+ pageReqVO.getMinuteCreator()+"%'");
        }
        if (pageReqVO.getMinuteCreator() == null) {
            queryWrapper.and(wrap->wrap.eq(MeetingInfoDO::getCreator,WebFrameworkUtils.getLoginUserId())
                    //.or().like(pageReqVO.getMinuteCreator()!= null,MeetingInfoDO::getCreator,pageReqVO.getMinuteCreator())
                    .or().exists("select 1 from of_meeting_minute_send_user su where   "+alias+".id = su.meeting_id and su.user_id ="+WebFrameworkUtils.getLoginUserId())
            );
        }

        PageResult<MeetingInfoDO> pageResult = meetingInfoMapper.selectPage(pageReqVO, queryWrapper);
        List<MeetingInfoDO> list = pageResult.getList();
        Long loginUserId = WebFrameworkUtils.getLoginUserId();
        List<MeetingInfoRespVO> collect = list.stream().map(item -> {
            MeetingInfoRespVO RespVO = BeanUtils.toBean(item, MeetingInfoRespVO.class);
            //设置会议参与者
            MPJLambdaWrapperX<MeetingPartDO> userWrapper = new MPJLambdaWrapperX<>();
            userWrapper.select(AdminUserDO::getNickname).distinct();
            userWrapper.eq(MeetingPartDO::getMeetingId,item.getId());
            userWrapper.innerJoin(AdminUserDO.class,AdminUserDO::getId,MeetingPartDO::getUserId);
            List<Map<String, Object>> maps = meetingPartMapper.selectMaps(userWrapper);
            if(!maps.isEmpty()){
                List<String> nickname = maps.stream().map(user -> (String)user.get("nickname")).collect(Collectors.toList());
                RespVO.setParticipantsList(nickname);
            }


            //获取会议日程附件
            Set<Long> agendaAttachs = item.getAgendaAttachs();
            if(agendaAttachs != null && !agendaAttachs.isEmpty()) {
                List<FileDO> fileDOS = fileMapper.selectList(FileDO::getId, agendaAttachs);
                if (!fileDOS.isEmpty()) {
                    RespVO.setAgendaAttachList(fileDOS);
                }
            }
            Set<Long> attachs = item.getAttachs();
            if(agendaAttachs != null && !agendaAttachs.isEmpty()) {
                List<FileDO> fileDOS = fileMapper.selectList(FileDO::getId, attachs);
                if (!fileDOS.isEmpty()) {
                    RespVO.setAttachList(fileDOS);
                }
            }

            List<MeetingMinutesDO> meetingMinutesDOS = null;
            //会议创建者，查看全部会议纪要
            if(item.getCreator().equals(String.valueOf(loginUserId))){
                meetingMinutesDOS = meetingMinutesMapper.selectList(MeetingMinutesDO::getMeetingId, item.getId(),
                        MeetingMinutesDO::getCreator, loginUserId);
            }else{
                //会议纪要 分派者
                List<MeetingMinuteSendUserDO> msendUserList = meetingMinuteSendUserMapper.selectList(MeetingMinuteSendUserDO::getMeetingId,item.getId(),
                        MeetingMinuteSendUserDO::getSendUserId,loginUserId);
                if(!msendUserList.isEmpty()){
                    List<Long> minuteIdList = msendUserList.stream().map(ms -> ms.getMinuteId()).collect(Collectors.toList());
                    meetingMinutesDOS = meetingMinutesMapper.selectList(MeetingMinutesDO::getId,minuteIdList);
                }
            }

            if(meetingMinutesDOS != null){
                List<MeetingMinutesRespVO> meetingMinueList =  meetingMinutesDOS.stream().map(minute->{
                    MeetingMinutesRespVO minutesRespVO = BeanUtils.toBean(minute, MeetingMinutesRespVO.class);
                    Long minuteAttach = minutesRespVO.getMinuteAttach();
                    if(minuteAttach != null){
                        FileDO fileDO = fileMapper.selectById(minuteAttach);
                        minutesRespVO.setFileDO(fileDO);
                    }
                    return minutesRespVO;
                }).collect(Collectors.toList());
                RespVO.setMinuteList(meetingMinueList);
            }
            return RespVO;
        }).collect(Collectors.toList());
        PageResult<MeetingInfoRespVO> result = new PageResult<>() ;
        result.setList(collect).setTotal(pageResult.getTotal());
        return result;
    }

    @Override
    public PageResult<MeetingRespVO> getMeetingTaskPage(MeetingInfoPageReqVO pageReqVO) {
        MPJLambdaWrapperX<MeetingInfoDO> queryWrapper = new MPJLambdaWrapperX<>();
        //获取MeetingInfoDO 表的别名
        String alias = queryWrapper.getAlias();
        queryWrapper.likeIfPresent(MeetingInfoDO::getName, pageReqVO.getName())
                .eqIfPresent(MeetingInfoDO::getTypeId,pageReqVO.getTypeId())
                .betweenIfPresent(MeetingInfoDO::getStartTime, pageReqVO.getStartTime());
        queryWrapper.and(wrap->wrap.eq(MeetingInfoDO::getCreator,WebFrameworkUtils.getLoginUserId())
                ////.or().eq(MeetingInfoDO::getTaskGenUserId,WebFrameworkUtils.getLoginUserId())
                //.or().eq(MeetingInfoDO::getMainRespUserId,WebFrameworkUtils.getLoginUserId())
                .or().exists("select 1 from of_meeting_minutes min where "+alias+".id = min.meeting_id and min.deleted =0  " +
                        "and (min.main_resp_user_id ="+WebFrameworkUtils.getLoginUserId() +" or min.task_gen_user_id ="+WebFrameworkUtils.getLoginUserId()+")")
        );
        if(pageReqVO.getStatus() != null){
            //未开始
            if(pageReqVO.getStatus() ==1){
                queryWrapper.gtIfPresent(MeetingInfoDO::getStartTime,new DateTime());
            }else  if(pageReqVO.getStatus() ==2){
                //进行中
                queryWrapper.leIfPresent(MeetingInfoDO::getStartTime,new DateTime())
                        .geIfPresent(MeetingInfoDO::getEndTime,new DateTime());
            }else if(pageReqVO.getStatus() ==3){
                //已结束
                queryWrapper.ltIfPresent(MeetingInfoDO::getEndTime,new DateTime());
            }
        }
        if(pageReqVO.getStatus() != null && pageReqVO.getStatus() == 3){
            //任务跟进中
            queryWrapper.exists("select 1 from of_task_info tsk where "+alias+".id = tsk.meeting_id " +
                    " and ts.status  not in (5,99) ");
        }else if(pageReqVO.getStatus() != null && pageReqVO.getStatus() == 4 ) {
                //已归档
            queryWrapper.exists("select 1 from of_task_info tsk where "+alias+".id = tsk.meeting_id " +
                    " and ts.status = 99 ");
        }else  if(pageReqVO.getIsHaveTask() != null){
            //有任务
            if(pageReqVO.getIsHaveTask() ==1){
               queryWrapper.exists("select 1 from of_task_info tsk where "+alias+".id = tsk.meeting_id ");
            }else{
                //没有任务
                queryWrapper.notExists("select 1 from of_task_info tsk where "+alias+".id = tsk.meeting_id ");
            }
        }
        PageResult<MeetingInfoDO> pageResult = meetingInfoMapper.selectPage(pageReqVO, queryWrapper);
        List<MeetingInfoDO> list = pageResult.getList();
        List<MeetingRespVO> collect = list.stream().map(item -> {
            MeetingRespVO meetingTaskRespVO = BeanUtils.toBean(item, MeetingRespVO.class);

            List<MeetingPartDO> meetingPartDOS = meetingPartMapper.selectList(MeetingPartDO::getMeetingId, item.getId());
            List<MeetingPartRespVO> partList = meetingPartDOS.stream().map(part -> {
                MeetingPartRespVO meetingPartRespVO = BeanUtils.toBean(part, MeetingPartRespVO.class);
                AdminUserDO adminUserDO = userMapper.selectById(part.getUserId());
                if(adminUserDO != null){
                    meetingPartRespVO.setUserName(adminUserDO.getNickname());
                }
                return meetingPartRespVO;
            }).collect(Collectors.toList());
            meetingTaskRespVO.setParticipantList(partList);
            MPJLambdaWrapperX<MeetingMinutesDO> minutesWrapper = new MPJLambdaWrapperX<>();
            //获取MeetingInfoDO 表的别名
            String malias = minutesWrapper.getAlias();
            minutesWrapper.eq(MeetingMinutesDO::getMeetingId,item.getId());
            minutesWrapper.and(wrap->wrap.eq(MeetingMinutesDO::getCreator,WebFrameworkUtils.getLoginUserId())
                    .or().exists("select 1 from of_meeting_minute_send_user su where "+malias+".id = su.minute_id and su.deleted =0  " +
                            "and su.user_id ="+WebFrameworkUtils.getLoginUserId() )
            );
            List<MeetingMinutesDO> meetingMinutesDOS = meetingMinutesMapper.selectList(MeetingMinutesDO::getMeetingId, item.getId());
            List<MeetingMinutesRespVO> minuteList = meetingMinutesDOS.stream().map(minute -> {
                MeetingMinutesRespVO minutesRespVO = BeanUtils.toBean(minute, MeetingMinutesRespVO.class);
                Long minuteAttach = minutesRespVO.getMinuteAttach();
                if(minuteAttach!= null){
                    FileDO fileDO = fileMapper.selectById(minuteAttach);
                    minutesRespVO.setMinuteAttachFile(fileDO);
                }

                return minutesRespVO;
            }).collect(Collectors.toList());
            meetingTaskRespVO.setMeetingMinutesList(minuteList);

            //获取会议日程附件
            Set<Long> agendaAttachs = item.getAgendaAttachs();
            if(agendaAttachs != null && !agendaAttachs.isEmpty()) {
                List<FileDO> fileDOS = fileMapper.selectList(FileDO::getId, agendaAttachs);
                if (!fileDOS.isEmpty()) {
                    meetingTaskRespVO.setAgendaAttachList(fileDOS);
                }
            }
            //获取会议纪要附件
            Set<Long> mitAttachs = item.getMinutesAttachs();
            if(mitAttachs != null && !mitAttachs.isEmpty()) {
                List<FileDO> fileDOS = fileMapper.selectList(FileDO::getId, mitAttachs);
                if (!fileDOS.isEmpty()) {
                    meetingTaskRespVO.setMinutesAttachList(fileDOS);
                }
            }
            //任务
            if(pageReqVO.getIsHaveTask() != null && pageReqVO.getIsHaveTask() ==2){
                return meetingTaskRespVO;
            }
            List<TaskInfoDO> taskInfoDOS = taskInfoMapper.selectList(TaskInfoDO::getMeetingId, item.getId(),TaskInfoDO::getTaskLevel,1);
            List<MeetingTaskRespVO> taskRespList = encapTask(taskInfoDOS);

            //是否有任务
            if(taskInfoDOS.isEmpty()){
                meetingTaskRespVO.setIsHaveTask(0);
            }else{
                meetingTaskRespVO.setIsHaveTask(1);
            }
            int closedNum = 0;
            Boolean isEdit = true;
            for(TaskInfoDO task:taskInfoDOS){
                //完成任务
                if(task.getStatus() != null && task.getStatus() != 1 && isEdit){
                    isEdit = false;
                }
                if(task.getStatus() != null && task.getStatus() == 99){
                    closedNum +=1;
                }
            }
            meetingTaskRespVO.setIsEdit(isEdit);
            //任务数
            meetingTaskRespVO.setTaskNum(taskRespList.size());
            //完成任务数
            meetingTaskRespVO.setClosedTaskNum(closedNum);
            meetingTaskRespVO.setTaskList(taskRespList);
            return meetingTaskRespVO;

        }).collect(Collectors.toList());
        PageResult<MeetingRespVO> result = new PageResult<>();
        result.setList(collect).setTotal(pageResult.getTotal());
        return result;
    }

    @Override
    public JSONObject getMeetingBaseStat(MeetingInfoPageReqVO pageReqVO) {
        MPJLambdaWrapperX<MeetingInfoDO> queryWrapper = new MPJLambdaWrapperX<>();

        queryWrapper.likeIfPresent(MeetingInfoDO::getName, pageReqVO.getName())
                .betweenIfPresent(MeetingInfoDO::getStartTime, pageReqVO.getStartTime());
        List<MeetingInfoDO> meetingInfoDOS = meetingInfoMapper.selectList(queryWrapper);
        int partCnt = 0;
        int minuteCnt = 0;
        int meetingLong  = 0;
        for(MeetingInfoDO m:meetingInfoDOS){
            if(m.getParticipants() != null) {
                partCnt += m.getParticipants().size();
            }
            if(m.getMinutesAttachs() != null && !m.getMinutesAttachs().isEmpty()){
                minuteCnt ++;
            }
            if(m.getTimeLong() != null){
                meetingLong += m.getTimeLong();
            }
        }

        JSONObject result = new JSONObject();
        result.put("count",meetingInfoDOS.size());
        result.put("partCnt",partCnt);
        result.put("minuteCnt",minuteCnt);
        result.put("meetingLong",meetingLong);
        return result;
    }

    @Override
    public List<Map<String, Object>> getMeetingTypeStat(MeetingInfoPageReqVO pageReqVO) {
        MPJLambdaWrapperX<MeetingInfoDO> queryWrapper = new MPJLambdaWrapperX<>();
        queryWrapper.select("label,count(*) as cnt");
        queryWrapper.likeIfPresent(MeetingInfoDO::getName, pageReqVO.getName())
                .betweenIfPresent(MeetingInfoDO::getStartTime, pageReqVO.getStartTime());
        queryWrapper.eq(DictDataDO::getDictType, DicConstants.MEETING_DIC_TYPE);
        queryWrapper.rightJoin(DictDataDO.class,DictDataDO::getValue,MeetingInfoDO::getTypeId);
        queryWrapper.groupBy(DictDataDO::getLabel);
        List<Map<String, Object>> maps = meetingInfoMapper.selectMaps(queryWrapper);
        return maps;
    }

    public  List<MeetingTaskRespVO> encapTask(List<TaskInfoDO> taskInfoDOS ){
        List<MeetingTaskRespVO> taskRespList = taskInfoDOS.stream().map(task -> {
            MeetingTaskRespVO taskRespVO = BeanUtils.toBean(task, MeetingTaskRespVO.class);

            //获取子任务
            MPJLambdaWrapperX<TaskInfoDO> taskWrapper = new MPJLambdaWrapperX<>();
            taskWrapper.eq(TaskInfoDO::getParentId,task.getId())
                    .eq(TaskInfoDO::getTaskLevel,2);
            List<TaskInfoDO> childTaskList = taskInfoMapper.selectList(taskWrapper);

            List<MeetingTaskRespVO> meetingTaskRespVOS = childTaskList.stream().map(childTask->{
                MeetingTaskRespVO taskRespVO1 = BeanUtils.toBean(childTask, MeetingTaskRespVO.class);
                taskRespVO1.setStatusName(TaskStatusEnum.valueOf(taskRespVO1.getStatus(),childTask.getTaskLevel()));
                //主办部门 和人员
                setMainRespInfo(taskRespVO1,childTask.getId(),1);
                //设置协办部门和人员
                setMainRespInfo(taskRespVO1,childTask.getId(),2);
                //设置反馈信息
                setFeedbackInfo(taskRespVO1,childTask.getId());

                List<Long> taskAttachment = childTask.getTaskAttachment();
                List<FileDO> fileDOS = fileMapper.selectList(FileDO::getId, taskAttachment);
                taskRespVO1.setTaskAttachmentList(fileDOS);
                return taskRespVO1;
            }).collect(Collectors.toList());


            taskRespVO.setChildren(meetingTaskRespVOS);

            taskRespVO.setStatusName(TaskStatusEnum.valueOf(taskRespVO.getStatus(), taskRespVO.getTaskLevel()));
            List<Long> taskAttachment = task.getTaskAttachment();
            List<FileDO> fileDOS = fileMapper.selectList(FileDO::getId, taskAttachment);
            taskRespVO.setTaskAttachmentList(fileDOS);
            //主办部门 和人员
            setMainRespInfo(taskRespVO,task.getId(),1);
            //设置协办部门和人员
            setMainRespInfo(taskRespVO,task.getId(),2);
            //设置反馈信息
            setFeedbackInfo(taskRespVO,task.getId());

            return taskRespVO;
        }).collect(Collectors.toList());
        return taskRespList;
    }

    private void setMainRespInfo(MeetingTaskRespVO taskRespVO,Long taskId,Integer handleType){
        List<TaskHandlerDO> taskHandlerDOS = taskHandlerMapper.selectList(TaskHandlerDO::getTaskId, taskId,
                TaskHandlerDO::getHandlerType,handleType

        );
        if(!taskHandlerDOS.isEmpty()){
            List<TaskHandlerRespVO> taskRespVo = taskHandlerDOS.stream().map(tashHandle -> {
                TaskHandlerRespVO taskHandlerRespVO = BeanUtils.toBean(tashHandle, TaskHandlerRespVO.class);
                DeptDO deptDO = deptMapper.selectById(tashHandle.getDeptId());
                if(deptDO != null){
                    taskHandlerRespVO.setDeptName(deptDO.getName());
                }
                AdminUserDO adminUserDO = userMapper.selectById(tashHandle.getUserId());
                if(adminUserDO != null){
                    taskHandlerRespVO.setUserName(adminUserDO.getNickname());
                }
                return taskHandlerRespVO;
            }).collect(Collectors.toList());

            if(taskRespVO.getTaskHandlerList() != null ){
                taskRespVO.getTaskHandlerList().addAll(taskRespVo);
            }else {
                taskRespVO.setTaskHandlerList(taskRespVo);
            }
            TaskHandlerDO taskHandlerDO = taskHandlerDOS.get(0);
            DeptDO deptDO = deptMapper.selectById(taskHandlerDO.getDeptId());
            if(deptDO != null){
                if(handleType == 1){
                    taskRespVO.setMainRespDeptId(deptDO.getId());
                    taskRespVO.setMainRespDeptName(deptDO.getName());
                }else{
                    taskRespVO.setLesserRespDeptId(deptDO.getId());
                    taskRespVO.setLesserRespDeptName(deptDO.getName());
                }
            }
            AdminUserDO adminUserDO = userMapper.selectById(taskHandlerDO.getUserId());
            if(adminUserDO != null){
                if(handleType == 1) {
                    taskRespVO.setMainRespUserId(adminUserDO.getId());
                    taskRespVO.setMainRespUserName(adminUserDO.getNickname());
                }else{
                    taskRespVO.setLesserRespUserId(adminUserDO.getId());
                    taskRespVO.setLesserRespUserName(adminUserDO.getNickname());
                }
            }
        }
    }

    private void setFeedbackInfo(MeetingTaskRespVO taskRespVO,Long taskId){
        LambdaQueryWrapper<TaskFeedbackDO> wrapper = new LambdaQueryWrapper<TaskFeedbackDO>().eq(TaskFeedbackDO::getTaskId, taskId);
        wrapper.orderByDesc(TaskFeedbackDO::getId);
        List<TaskFeedbackDO> taskHandlerDOS = taskFeedbackMapper.selectList(wrapper);
        if(!taskHandlerDOS.isEmpty()){
            TaskFeedbackDO feedbackDO = taskHandlerDOS.get(0);
            taskRespVO.setFeedbackContent(feedbackDO.getFeedbackContent());

            List<Long> feedbackAttachment = feedbackDO.getFeedbackAttachment();
            List<FileDO> fileDOS = fileMapper.selectList(FileDO::getId, feedbackAttachment);
            taskRespVO.setFeedbackAttachList(fileDOS);
        }
    }

}